﻿using System;
using System.Collections.Generic;
using System.Linq;
using Mono.Cecil;
using Mono.Cecil.Cil;

namespace Ue.Aop
{
    public static class ModuleExtensions
    {
        public static IEnumerable<Tuple<TypeDefinition, IEnumerable<CustomAttribute>>> GetTypes(this ModuleDefinition module, params TypeReference[] typeAttributeTypes)
        {
            if(typeAttributeTypes==null || typeAttributeTypes.Count()==0)
            {
                return Enumerable.Empty<Tuple<TypeDefinition, IEnumerable<CustomAttribute>>>();
            }

            return module
                .Types
                .SelectMany(type => type.GetAllTypes())
                .Select(type =>
                {
                    return Tuple.Create(
                        type,
                        type.CustomAttributes.Where(attr =>
                        {
                            var attrDef = attr.AttributeType.Resolve();
                            return typeAttributeTypes.Any(t => attrDef.Implements(t) || attrDef.DerivesFrom(t));
                        })
                    );
                })
                .Where(item=>item.Item2.Count()>0);
        }
    }
}
